/*
 * REFXMLSchemaElementDecl.h
 *
 *  Created on: Apr 1, 2013
 *      Author: Lucifer
 */

#ifndef	__BFX_REFXMLSCHEMAELEMENTDECL_H__
#define	__BFX_REFXMLSCHEMAELEMENTDECL_H__

#include "../core/REFXMLQualifiedName.h"
#include "REFXMLSchemaElement.h"
#include "REFXMLSchemaDecl.h"
#include "REFXMLSchemaAttDef.h"
#include "REFXMLContentValidator.h"

namespace BFX
{

//////////////////////////////////////////////////////////////////////////////
// This class describes an element type and potential values.
class REFXMLSchemaElementDecl : public REFXMLSchemaDecl
{
public:
	REFXMLSchemaElementDecl(REFXMLQualifiedName* pName, const UniString& strPrefix, SchemaType schemaType);
	virtual ~REFXMLSchemaElementDecl();

	REFXMLSchemaElement* GetSchemaElement() const;
	void SetSchemaElement(REFXMLSchemaElement* pSchemaElement);

	// Retrieves the attribute definition of the named attribute.
	REFXMLSchemaAttDef* GetAttDef(REFXMLQualifiedName* pName) const;
	REFXMLSchemaAttDefMap* GetAttDefs() const;
	REFXMLSchemaAttDefArray* GetDefaultAttDefs() const;
	// Add a new attribute definition.
	void AddAttDef(REFXMLSchemaAttDef* pAttDef);

	bool IsIdDeclared() const;
	void SetIdDeclared(bool bValue);
	bool HasNonCDataAttribute() const;
	void SetHasNonCDataAttribute(bool bValue);
	bool HasDefaultAttribute() const;

	REFXMLContentValidator* GetContentValidator() const;
	void SetContentValidator(REFXMLContentValidator* pContentValidator);

private:
	REF<REFXMLSchemaElement>		m_pSchemaElement;
	REF<REFXMLSchemaAttDefMap>		m_pAttdefs;
	REF<REFXMLSchemaAttDefArray>	m_pDefaultAttdefs;
	REF<REFXMLContentValidator>		m_pContentValidator;

	bool	m_bIsIdDeclared;
	bool	m_bHasNonCDataAttribute;
	bool	m_bHasRequiredAttribute;
};

//////////////////////////////////////////////////////////////////////////////

inline REFXMLSchemaElementDecl::REFXMLSchemaElementDecl(REFXMLQualifiedName* pName, const UniString& strPrefix, SchemaType schemaType)
	: REFXMLSchemaDecl(pName, strPrefix)
{
	m_pAttdefs = new REFXMLSchemaAttDefMap();
	m_pDefaultAttdefs = new REFXMLSchemaAttDefArray();

	m_bIsIdDeclared = false;
	m_bHasNonCDataAttribute = false;
	m_bHasRequiredAttribute = false;
}
inline REFXMLSchemaElementDecl::~REFXMLSchemaElementDecl()
{
}

inline REFXMLSchemaElement* REFXMLSchemaElementDecl::GetSchemaElement() const
{
	return m_pSchemaElement;
}
inline void REFXMLSchemaElementDecl::SetSchemaElement(REFXMLSchemaElement* pSchemaElement)
{
	m_pSchemaElement = pSchemaElement;
}

// Retrieves the attribute definition of the named attribute.
inline REFXMLSchemaAttDef* REFXMLSchemaElementDecl::GetAttDef(REFXMLQualifiedName* pName) const
{
	REFXMLSchemaAttDefMap::POSITION entry = m_pAttdefs->LookupEntry(pName);
	return entry == NULL ? NULL : entry->value;
}
inline REFXMLSchemaAttDefMap* REFXMLSchemaElementDecl::GetAttDefs() const
{
	return m_pAttdefs;
}
inline REFXMLSchemaAttDefArray* REFXMLSchemaElementDecl::GetDefaultAttDefs() const
{
	return m_pDefaultAttdefs;
}
// Add a new attribute definition.
inline void REFXMLSchemaElementDecl::AddAttDef(REFXMLSchemaAttDef* pAttDef)
{
	m_pAttdefs->Set(pAttDef->GetName(), pAttDef);
	if (pAttDef->GetPresence() == REFXMLSchemaDecl::UseRequired || pAttDef->GetPresence() == REFXMLSchemaDecl::UseRequiredFixed)
	{
		m_bHasRequiredAttribute = true;
	}
	if (pAttDef->GetPresence() == REFXMLSchemaDecl::UseDefault || pAttDef->GetPresence() == REFXMLSchemaDecl::UseFixed)
	{
		// Not adding RequiredFixed here
		m_pDefaultAttdefs->Add(pAttDef);
	}
}

inline bool REFXMLSchemaElementDecl::IsIdDeclared() const
{
	return m_bIsIdDeclared;
}
inline void REFXMLSchemaElementDecl::SetIdDeclared(bool bValue)
{
	m_bIsIdDeclared = bValue;
}
inline bool REFXMLSchemaElementDecl::HasNonCDataAttribute() const
{
	return m_bHasNonCDataAttribute;
}
inline void REFXMLSchemaElementDecl::SetHasNonCDataAttribute(bool bValue)
{
	m_bHasNonCDataAttribute = bValue;
}
inline bool REFXMLSchemaElementDecl::HasDefaultAttribute() const
{
	return (m_pDefaultAttdefs->GetSize() > 0);
}

inline REFXMLContentValidator* REFXMLSchemaElementDecl::GetContentValidator() const
{
	return m_pContentValidator;
}
inline void REFXMLSchemaElementDecl::SetContentValidator(REFXMLContentValidator* pContentValidator)
{
	m_pContentValidator = pContentValidator;
}

//////////////////////////////////////////////////////////////////////////////

typedef	REFWrapper<HashMap<REF<REFXMLQualifiedName>, REF<REFXMLSchemaElementDecl> > >	REFXMLSchemaElementDeclMap;

}	//	namespace BFX

#endif	//	__BFX_REFXMLSCHEMAELEMENTDECL_H__
